/* --------------------------- creators/themedui.js ------------------------- */
VED.replaceClass = 'ved';

(function() {

   VED.replace = function( element, config ) {
      return createInstance( element, config, null, VED.ELEMENT_MODE_REPLACE );
   };

   VED.appendTo = function( element, config, data ) {
      return createInstance( element, config, data, VED.ELEMENT_MODE_APPENDTO );
   };

   VED.replaceAll = function() {
      var textareas = document.getElementsByTagName( 'textarea' );

      for ( var i = 0; i < textareas.length; i++ ) {
         var config = null,
            textarea = textareas[ i ];

         // The "name" and/or "id" attribute must exist.
         if ( !textarea.name && !textarea.id )
            continue;

         if ( typeof arguments[ 0 ] == 'string' ) {
            // The textarea class name could be passed as the function
            // parameter.

            var classRegex = new RegExp( '(?:^|\\s)' + arguments[ 0 ] + '(?:$|\\s)' );

            if ( !classRegex.test( textarea.className ) )
               continue;
         } else if ( typeof arguments[ 0 ] == 'function' ) {
            // An assertion function could be passed as the function parameter.
            // It must explicitly return "false" to ignore a specific <textarea>.
            config = {};
            if ( arguments[ 0 ]( textarea, config ) === false )
               continue;
         }

         this.replace( textarea, config );
      }
   };

   /** @class VED.editor */

   VED.editor.implement({
      addMode: function( mode, exec ) {
         ( this._.modes || ( this._.modes = {} ) )[ mode ] = exec;
      },

      setMode: function( newMode, callback ) {
         var editor = this;

         var modes = this._.modes;

         // Mode loading quickly fails.
         if ( newMode == editor.mode || !modes || !modes[ newMode ] )
            return;

         editor.fire( 'beforeSetMode', newMode );

         if ( editor.mode ) {
            var isDirty = editor.checkDirty();

            editor._.previousMode = editor.mode;

            editor.fire( 'beforeModeUnload' );

            // Detach the current editable.
            editor.editable( 0 );

            // Clear up the mode space.
            editor.ui.space( 'contents' ).setHtml( '' );

            editor.mode = '';
         }

         // Fire the mode handler.
         this._.modes[ newMode ]( function() {
            // Set the current mode.
            editor.mode = newMode;

            if ( isDirty !== undefined ) {
               !isDirty && editor.resetDirty();
            }

            // Delay to avoid race conditions (setMode inside setMode).
            setTimeout( function() {
               editor.fire( 'mode' );
               callback && callback.call( editor );
            }, 0);
         });
      },

      resize: function( width, height, isContentHeight, resizeInner ) {
         var container = this.container,
            contents = this.ui.space( 'contents' ),
            contentsFrame = VED.env.webkit && this.document && this.document.getWindow().$.frameElement,
            outer = resizeInner ? container.getChild( 1 ) : container;

         // Set as border box width. (#5353)
         outer.setSize( 'width', width, true );

         // WebKit needs to refresh the iframe size to avoid rendering issues. (1/2) (#8348)
         contentsFrame && ( contentsFrame.style.width = '1%' );

         // Get the height delta between the outer table and the content area.
         // If we're setting the content area's height, then we don't need the delta.
         var delta = isContentHeight ? 0 : ( outer.$.offsetHeight || 0 ) - ( contents.$.clientHeight || 0 );
         contents.setStyle( 'height', Math.max( height - delta, 0 ) + 'px' );

         // WebKit needs to refresh the iframe size to avoid rendering issues. (2/2) (#8348)
         contentsFrame && ( contentsFrame.style.width = '100%' );

         // Emit a resize event.
         this.fire( 'resize' );
      },

      getResizable: function( forContents ) {
         return forContents ? this.ui.space( 'contents' ) : this.container;
      }
   
   });

   function createInstance( element, config, data, mode ) {
      if ( !VED.env.isCompatible )
         return null;

      element = VED.dom.element.get( element );

      // Avoid multiple inline editor instances on the same element.
      if ( element.getEditor() )
         throw 'The editor instance "' + element.getEditor().name + '" is already attached to the provided element.';

      // Create the editor instance.
      var editor = new VED.editor( config, element, mode );

      // Do not replace the textarea right now, just hide it. The effective
      // replacement will be done later in the editor creation lifecycle.
      if ( mode == VED.ELEMENT_MODE_REPLACE )
         element.setStyle( 'visibility', 'hidden' );

      data && editor.setData( data, null, true );

      // Once the editor is loaded, start the UI.
      editor.on( 'loaded', function() {
         loadTheme( editor );

         if (  mode == VED.ELEMENT_MODE_REPLACE && editor.config.autoUpdateElement )
            attachToForm( editor );

         editor.setMode( editor.config.startupMode, function() {
            // Clean on startup.
            editor.resetDirty();

            // Editor is completely loaded for interaction.
            editor.status = 'ready';
				editor.fireOnce( 'instanceReady' );
            VED.fire( 'instanceReady', null, editor );
         });
      });

      editor.on( 'destroy', destroy );
      return editor;
   }

   function destroy() {
      var editor = this,
         container = editor.container,
         element = editor.element;

      if ( container ) {
         container.clearCustomData();
         container.remove();
      }

      if ( element ) {
         element.clearCustomData();
         editor.elementMode == VED.ELEMENT_MODE_REPLACE && element.show();
         delete editor.element;
      }
   }

   var themedTpl;

   function loadTheme( editor ) {
      var name = editor.name,
         element = editor.element,
         elementMode = editor.elementMode;

      // Get the HTML for the predefined spaces.
      var titleHtml = editor.fire( 'uiSpace', { space: 'title', html: '' } ).html;
      var topHtml = editor.fire( 'uiSpace', { space: 'top', html: '' } ).html;
      var bottomHtml = editor.fire( 'uiSpace', { space: 'bottom', html: '' } ).html;

      if ( !themedTpl ) {
         themedTpl = VED.addTemplate( 'maincontainer', 
            '<{outerEl}' +
            ' id="ved_{name}"' +
            ' class="{id} ved ved_reset ved_chrome ved_editor_{name} ved_{langDir} ' + VED.env.cssClass + '" ' +
            ' dir="{langDir}"' +
            ' lang="{langCode}"' +
            ' role="application"' +
            ' aria-labelledby="ved_{name}_arialbl">' +
               // '<label for="{contentId}"><span id="ved_{name}_label" class="name">{titleText}</span>{titleFillingHtml}</label>' +
               '<span id="ved_{name}_arialbl" class="ved_voice_label">{voiceLabel}</span>' +
               '<{outerEl} class="ved_inner ved_reset" role="presentation">' +
                  '{titleHtml}' +
                  '{topHtml}' +
                  '<{outerEl} id="{contentId}" class="ved_contents ved_reset" role="presentation"></{outerEl}>' +
                  '{bottomHtml}' +
               '</{outerEl}>' +
            '</{outerEl}>'
         );
      }

      var container = VED.dom.element.createFromHtml( themedTpl.output({
         id: editor.id,
         name: name,
         langDir: editor.lang.dir,
         langCode: editor.langCode,
         voiceLabel: [ editor.lang.editor, editor.name ].join( ', ' ),
         // titleFillingHtml: editor.config.field_filling ? '<span class="filling-star">*</span>' : '',
         // titleText: editor.config.field_text || editor.lang.editor,
         titleHtml: titleHtml ? '<span id="' + editor.ui.spaceId( 'title' ) + '" class="ved_title" role="presentation" style="height:auto">' + titleHtml + '</span>' : '',
         topHtml: topHtml ? '<span id="' + editor.ui.spaceId( 'top' ) + '" class="ved_top ved_reset_all" role="presentation" style="height:auto">' + topHtml + '</span>' : '',
         contentId: editor.ui.spaceId( 'contents' ),
         bottomHtml: bottomHtml ? '<span id="' + editor.ui.spaceId( 'bottom' ) + '" class="ved_bottom ved_reset_all" role="presentation">' + bottomHtml + '</span>' : '',
         outerEl: VED.env.ie ? 'span' : 'div'   // #9571
      }));

      if ( elementMode == VED.ELEMENT_MODE_REPLACE ) {
         element.hide();
         container.insertAfter( element );
      } else
         element.append( container );

      editor.container = container;

      // Make top and bottom spaces unelectable, but not content space,
      // otherwise the editable area would be affected.
      titleHtml && editor.ui.space( 'title' ).unselectable();
      topHtml && editor.ui.space( 'top' ).unselectable();
      bottomHtml && editor.ui.space( 'bottom' ).unselectable();

      var width = editor.config.width, height = editor.config.height;
      if ( width )
         container.setStyle( 'width', VED.tools.cssLength( width ) );

      // The editor height is applied to the contents space.
      if ( height )
         editor.ui.space( 'contents' ).setStyle( 'height', VED.tools.cssLength( height ) );

      // Disable browser context menu for editor's chrome.
      container.disableContextMenu();

      // Redirect the focus into editor for webkit. (#5713)
      VED.env.webkit && container.on( 'focus', function() {
         editor.focus();
      });

      editor.fireOnce( 'uiReady' );
   }

   function attachToForm( editor ) {
      var element = editor.element;

      // If are replacing a textarea, we must
      if ( editor.elementMode == VED.ELEMENT_MODE_REPLACE && element.is( 'textarea' ) ) {
         var form = element.$.form && new VED.dom.element( element.$.form );
         if ( form ) {
            function onSubmit() {
               editor.updateElement();
            }
            form.on( 'submit', onSubmit );

            // Setup the submit function because it doesn't fire the
            // "submit" event.
            if ( !form.$.submit.nodeName && !form.$.submit.length ) {
               form.$.submit = VED.tools.override( form.$.submit, function( originalSubmit ) {
                  return function() {
                     editor.updateElement();

                     // For IE, the DOM submit function is not a
                     // function, so we need third check.
                     if ( originalSubmit.apply )
                        originalSubmit.apply( this, arguments );
                     else
                        originalSubmit();
                  };
               });
            }

            // Remove 'submit' events registered on form element before destroying.(#3988)
            editor.on( 'destroy', function() {
               form.removeListener( 'submit', onSubmit );
            });
         }
      }
   }

   // Replace all textareas with the default class name.
   window.onDomReady( function() {
      VED.replaceClass && VED.replaceAll( VED.replaceClass );
   });
})();

VED.config.startupMode = 'wysiwyg';






